﻿/// <reference path="../../../../SIR.Web/scripts/_references.js" />
/// <reference path="../../../../SIR.Web/scripts/jquery-1.9.1.js" />
/// <reference path="../../../../SIR.Web/scripts/angular.js" />
/// <reference path="../../../../SIR.Web/scripts/angular-mocks.js" />

/// <reference path="../../../../SIR.Web/app/app.js" />
/// <reference path="../../../../SIR.Web/app/common/common.js" />
/// <reference path="../../../../SIR.Web.Tests/JavaScript/sir-mock.js" />
/// <reference path="../../../../SIR.Web/app/authenticate/authenticate.js" />
/// <reference path="../../../../SIR.Web/app/authenticate/services/auth-service.js" />
/// <reference path="../../../../SIR.Web/app/authenticate/controllers/user-control-panel-controller.js" />

describe('User Control Panel Controller - Register:', function () {
	'use strict';
	// declare variables and modules
	var scope, location, controller, rootScope, $httpBackend, notifyService;

	beforeEach(module('ui.router'));
	beforeEach(module('app.common'));
	beforeEach(module('app.authenticate'));

	beforeEach(inject(function ($injector, $controller, $rootScope, authService, notify) {
		// intialize variables for each test
		notifyService = notify;
		$httpBackend = $injector.get('$httpBackend');
		rootScope = $rootScope;
		scope = $rootScope.$new();
		// expect the log in requests
		$httpBackend.expectPOST('/api/Authentication/LogIn').respond({ Successful: false, Content: null, Message: '' });
		controller = $controller('ControlPanelController', { $scope: scope, $state: {}, authService: authService });
		$httpBackend.flush();
		// spy on the controller functions
		spyOn(controller, 'handleRegisterReply').andCallThrough();
		spyOn(controller, 'showRegisterState').andCallThrough();
		spyOn(controller, 'showLoggedInState').andCallThrough();
		// spy on the notify functions
		spyOn(notifyService, 'warning').andCallThrough();
		spyOn(notifyService, 'error').andCallThrough();
		spyOn(notifyService, 'success').andCallThrough();

	}));
	// expect all web requests to have been handled
	afterEach(function () {
		$httpBackend.verifyNoOutstandingExpectation();
		$httpBackend.verifyNoOutstandingRequest();
	});

	describe('User Registers (Total: 7)', function () {
		it('[1] Produce \'Email is required\' message when user attempts to register with an empty email', function () {
			// show register screens
			scope.registerNewUser();
			// set the email, password, and confirmation
			scope.model.email = '';
			scope.model.password = 'password';
			scope.model.confirmPassword = 'password';
			// submit new user
			scope.createNewUser();
			// expect the reply was not handled
			expect(controller.handleRegisterReply).wasNotCalled();
			// expect to be in the register state
			expect(controller.showRegisterState).toHaveBeenCalled();
			// expect not to have gone to the logged in state
			expect(controller.showLoggedInState).wasNotCalled();
			// expect the warning was displayed
			expect(notifyService.warning).toHaveBeenCalledWith('Email is required');
			// expect the user is still null
			expect(scope.user).toBe(null);
			// expect the values to have been cleared
			expect(scope.model.email).toBe('');
			expect(scope.model.password).toBe('');
			expect(scope.model.confirmPassword).toBe('');
		});

		it('[2] Produce \'Password is required\' message when user attempts to register with an empty password', function () {
			// start registration process
			scope.registerNewUser();
			// populate email but not password
			scope.model.email = 'email';
			scope.model.password = '';
			scope.model.confirmPassword = 'password';
			// submit new user
			scope.createNewUser();
			// expect the reply was not handled
			expect(controller.handleRegisterReply).wasNotCalled();
			// expect to be in the register state
			expect(controller.showRegisterState).toHaveBeenCalled();
			// expect not to have gone to the logged in state
			expect(controller.showLoggedInState).wasNotCalled();
			// expect the warning was displayed
			expect(notifyService.warning).toHaveBeenCalledWith('Password is required');
			// expect the user is still null
			expect(scope.user).toBe(null);
			// expect the values to have been cleared
			expect(scope.model.email).toBe('email');
			expect(scope.model.password).toBe('');
			expect(scope.model.confirmPassword).toBe('');
		});

		it('[3] Produce \'Passwords do not match\' message when user attempt to register the password and confirmation fields not matching', function () {
			// start register process
			scope.registerNewUser();
			// set passwords to not match
			scope.model.email = 'email';
			scope.model.password = 'password';
			scope.model.confirmPassword = 'password2';
			// submit new user
			scope.createNewUser();
			// expect the reply was not handled
			expect(controller.handleRegisterReply).wasNotCalled();
			// expect to be in the register state
			expect(controller.showRegisterState).toHaveBeenCalled();
			// expect not to have gone to the logged in state
			expect(controller.showLoggedInState).wasNotCalled();
			// expect the warning was displayed
			expect(notifyService.warning).toHaveBeenCalledWith('Passwords do not match');
			// expect the user is still null
			expect(scope.user).toBe(null);
			// expect the values to have been cleared
			expect(scope.model.email).toBe('email');
			expect(scope.model.password).toBe('');
			expect(scope.model.confirmPassword).toBe('');
		});

		it('[4] Produce \'Email already used\' message when user attempts to register with an email that has already been used', function () {
			// set the response to fail because email is being used
			$httpBackend.expectPOST('/api/Authentication/Register').respond({ Successful: false, Content: null, Message: 'Email already used' });
			// start register process
			scope.registerNewUser();
			// complete all fields correctly
			scope.model.email = 'email';
			scope.model.password = 'password';
			scope.model.confirmPassword = 'password';
			scope.model.nickname = 'nickname';
			// submit new user
			scope.createNewUser();
			scope.$digest();
			$httpBackend.flush();
			// submit new user
			scope.createNewUser();
			// expect the reply was not handled
			expect(controller.handleRegisterReply).toHaveBeenCalled();
			// expect to be in the register state
			expect(controller.showRegisterState).toHaveBeenCalled();
			// expect not to have gone to the logged in state
			expect(controller.showLoggedInState).wasNotCalled();
			// expect the warning was displayed
			expect(notifyService.error).toHaveBeenCalledWith('Email already used');
			// expect the user is still null
			expect(scope.user).toBe(null);
			// expect the values to have been cleared
			expect(scope.model.email).toBe('email');
			expect(scope.model.password).toBe('');
			expect(scope.model.confirmPassword).toBe('');
		});

		it('[5] Produce \'Password failed to meet security standards\' message when user attempt to register with an invalid password', function () {
			$httpBackend.expectPOST('/api/Authentication/Register').respond({ Successful: false, Content: null, Message: 'Password failed to meet security standards' });
			scope.registerNewUser();
			scope.model.email = 'email';
			scope.model.password = 'password';
			scope.model.confirmPassword = 'password';
			scope.model.nickname = 'nickname';
			scope.createNewUser();
			scope.$digest();
			$httpBackend.flush();

			expect(controller.handleRegisterReply).toHaveBeenCalled();
			expect(controller.showRegisterState).toHaveBeenCalled();
			expect(controller.showLoggedInState).wasNotCalled();

			expect(notifyService.error).toHaveBeenCalledWith('Password failed to meet security standards');
			// expect the user is still null
			expect(scope.user).toBe(null);
			// expect the values to have been cleared
			expect(scope.model.email).toBe('email');
			expect(scope.model.password).toBe('');
			expect(scope.model.confirmPassword).toBe('');
		});

		it('[6] Produce \'Account created and email dropped into folder\' when user registers with only an email and a password', function () {
			// populate the response with a success message
			$httpBackend.expectPOST('/api/Authentication/Register').respond({ Successful: true, Content: {}, Message: 'Account has been created' });
			// start register process
			scope.registerNewUser();
			// populate field valuues
			scope.model.email = 'email';
			scope.model.password = 'password';
			scope.model.confirmPassword = 'password';
			scope.model.nickname = 'nickname';
			// create the new user
			scope.createNewUser();
			scope.$digest();
			$httpBackend.flush();
			// expect the message to have been handled
			expect(controller.handleRegisterReply).toHaveBeenCalled();
			// expect the register state was entered
			expect(controller.showRegisterState).toHaveBeenCalled();
			// expect to be in the logged in state
			expect(controller.showLoggedInState).toHaveBeenCalled();
			// expect a success message
			expect(notifyService.success).toHaveBeenCalled();
			// expect the user is not null
			expect(scope.user).toNotBe(null);
			// expect the values to have been cleared
			expect(scope.model.email).toBe('');
			expect(scope.model.password).toBe('');
			expect(scope.model.confirmPassword).toBe('');
		});

		it('[7] Produce \'Account created and email dropped into folder\' when user registers by filling out all fields', function () {
			// populate the response with a success message
			$httpBackend.expectPOST('/api/Authentication/Register').respond({ Successful: true, Content: {}, Message: 'Account has been created' });
			// start register process
			scope.registerNewUser();
			// populate field valuues
			scope.model.email = 'email';
			scope.model.password = 'password';
			scope.model.confirmPassword = 'password';
			scope.model.nickname = 'nickname';
			// create the new user
			scope.createNewUser();
			scope.$digest();
			$httpBackend.flush();
			// expect the message to have been handled
			expect(controller.handleRegisterReply).toHaveBeenCalled();
			// expect the register state was entered
			expect(controller.showRegisterState).toHaveBeenCalled();
			// expect to be in the logged in state
			expect(controller.showLoggedInState).toHaveBeenCalled();
			// expect a success message
			expect(notifyService.success).toHaveBeenCalled();
			// expect the user is not null
			expect(scope.user).toNotBe(null);
			// expect the values to have been cleared
			expect(scope.model.email).toBe('');
			expect(scope.model.password).toBe('');
			expect(scope.model.confirmPassword).toBe('');
		});
	});
});